Optimizing startup of web app
Recently I read an article on HN on how to Get 100/100 Google Page Speed Score,
and wondered how high score I can get with my online text editor/IDE ...
The editor is a web app with lots of JavaScript, so it's quite heavy compared to normal web sites.
What I started out with
A test run of webide.se gave me a Google PageSpeed Insights score of 33 / 100 for mobile and 40 / 100 for desktop, and the overall rating of, quote: "Poor".
Google uses page speed to sort search results, so improving the score would be good for Search Engine Optimization (SEO).
Lets fire up Chromium dev tools and the Performance tab to see what's going on ...
That's around 1000ms (one second) to load the app, which isn't bad, but it's idle for ca 700ms, and we can probably do something about that.
If you look at the waterfall we can see that the browser loads six files at a time, as the editor has a lot of JS files, that's a lot of time wasted.
I also tested it in production where HTTP2 is enabled, but it still looks like the waterfall, although smoother.
Let's inline ALL 102 JavaScript files into index.htm and see if we can get rid of the idle time (which is probably caused by network latency) ...
The idle time has now gone from 700ms to 10ms and the total load time from 1000ms to around 230ms!
Lets see what PageSpeed Insights say now when we've made it 3 times faster:
65 / 100 (+32) on mobile and 79 / 100 (+39) on Desktop, with the overall rating of, quote: "Needs Work" ...
This is what PageSpeed Insights suggests I should do:
- Prioritize visible content
- Minify HTML
- Eliminate render-blocking JavaScript and CSS in above-the-fold content
- Enable compression
- Minify CSS
It already beleaves the JavaScript is minified because the first of the 102 scripts is minified, while the rest is not.
Lets see what happens with the load time if we do minify all of the JavaScript's ...
There's some gotchas when inlining JavaScript though, as the HTML parser will have trouble with ending script tags inside JavaScript strings. But I got it to work by raplacing all ending script tags with <\\/script> and the old trick of putting everything inside HTML comments.
This is the Nodejs script I use to make the bundle:
After minifying JavaScript
The size of the bundle.htm went from 1,282,258 bytes (298,089 gzip) to 546,232 bytes (147,959 gzip) but the actual load time went up from 230ms to 260ms and idle time to 50ms. So by minifying all JavaScript the loading time increased slightly, I did not expected that!
When it comes to optimizations - do not take things for granted!
Never do premature optimizations. Always measure the result of the optimization!
Lets see what PageSpeed Insights think of our minified JavaScript:
74 / 100 (+9) on mobile and 89 / 100 (+14) on Desktop. It gave us an reward for the lowering the file size!
That tiny CSS file is still slowing us down though, as the app needs to wait for it to render.
Inlining CSS requires some extra work as we have to change all the relative paths ... What else can we do ?
There's a JavaScript file that dynamically loads a font. Lets see if not loading the font will improve things:
Loading time went from 230 to ca 200ms! Around 10ms idle time (with JavaScript's minified). 74 / 100 on mobile and 89 / 100 on desktop, so no improvement on PageSpeed Insights score from skipping the fonts!
There's also a JavaScript that loads three icons that are never displayed, lets see if not loading those have any effect ...
Idle time and total load time went up ca 40ms, not as expected.
Inline the CSS
I made this Nodejs script to do the inlining, same as above, but also inlines CSS. It doesn't minify the CSS or HTML, but there's modules for that, so it shouln't be that difficult to add.